# -*- coding: utf-8 -*-
import sys
import pygame

class GameBase(object):

    def __init__(self, **kwargs):
        self.game_name = kwargs.get('game_name')
        self.size = kwargs.get('screen_size')
        self.fps = kwargs.get('fps')
        self.font_name = kwargs.get('font_name')
        self.font_size = kwargs.get('font_size')
        self.display_mode = kwargs.get('display_mode')
        self.icon = kwargs.get('icon')

        pygame.init()
        pygame.mixer.init()
        pygame.display.set_caption(self.game_name)
        self.screen_size = self.screen_width, self.height = self.size
        self.icon and pygame.display.set_icon(pygame.image.load(self.icon))
        self.screen = pygame.display.set_mode(self.screen_size, self.display_mode)
        self.font = pygame.font.SysFont(self.font_name, self.font_size)
        self.clock = pygame.time.Clock()
        self.current_tick = 0
        self.background = pygame.Surface(self.screen_size)
        self.running = True
        self.key_binds = {}
        self.game_update_actions = {}
        self.draw_update_actions = []
        self.add_key_bind(pygame.K_p, self.pause_trigger)
        self.add_key_bind(pygame.K_ESCAPE, self.quit)

    def run(self):
        while True:
            self.current_tick = pygame.time.get_ticks()
            self.process_events()
            if self.running:
                self.update_game()
            self.update_display()
            self.clock.tick(self.fps)

    def pause_trigger(self):
        self.running = not self.running
        if not self.running:
            return
        self.update_next_time()

    def update_next_time(self):
        for action in self.game_update_actions.values():
            action['next_time'] = self.current_tick + action['interval']

    def quit(self):
        pygame.quit()
        sys.exit(0)

    def add_key_bind(self, key, action_fun, **kwargs):
        self.key_binds[key] = action_fun, kwargs

    def add_update_action(self, action_name, action_fun, interval=1000):
        next_time = self.current_tick + interval
        temp = dict(action_fun=action_fun, interval=interval, next_time=next_time)
        self.game_update_actions[action_name] = temp

    def add_display_action(self, action_fun):
        self.draw_update_actions.append(action_fun)

    def process_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quit()
            elif event.type == pygame.KEYDOWN:
                if event.key in self.key_binds:
                    action_fun, kwargs = self.key_binds.get(event.key)
                    action_fun(**kwargs)

    def update_game(self):
        for action in self.game_update_actions.values():
            if self.current_tick >= action['next_time']:
                action['next_time'] += action['interval']
                action['action_fun']()

    def update_display(self):
        for action_fun in self.draw_update_actions:
            action_fun()
        pygame.display.flip()

    def draw_background(self):
        self.screen.blit(self.background, (0, 0))
